home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 13 / CU Amiga Magazine's Super CD-ROM 13 (1997)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1997-08].iso / CUCD / Graphics / irit70 / src / irit / freefrm2.c < prev    next >
C/C++ Source or Header  |  1997-04-13  |  76KB  |  1,823 lines

  1. /*****************************************************************************
  2. *   "Irit" - the 3d (not only polygonal) solid modeller.             *
  3. *                                         *
  4. * Written by:  Gershon Elber                Ver 0.2, Mar. 1990   *
  5. ******************************************************************************
  6. * (C) Gershon Elber, Technion, Israel Institute of Technology                *
  7. ******************************************************************************
  8. *   Module to provide the required interfact for the cagd library for the    *
  9. * free form surfaces and curves.                         *
  10. *****************************************************************************/
  11.  
  12. #include <stdio.h>
  13. #include <math.h>
  14. #include "program.h"
  15. #include "allocate.h"
  16. #include "attribut.h"
  17. #include "objects.h"
  18. #include "primitiv.h"
  19. #include "geomat3d.h"
  20. #include "ip_cnvrt.h"
  21. #include "bool_lib.h"
  22. #include "freeform.h"
  23.  
  24. static IPObjectStruct *ComputeCurveIsoLines(IPObjectStruct *PObj,
  25.                         int Optimal);
  26. static IPObjectStruct *ComputeSurfaceIsoLines(IPObjectStruct *PObj,
  27.                           int Optimal);
  28. static IPObjectStruct *ComputeTrimSrfIsoLines(IPObjectStruct *PObj,
  29.                           int Optimal);
  30. static IPObjectStruct *ComputeTrivarIsoLines(IPObjectStruct *PObj,
  31.                          int Optimal);
  32. static IPObjectStruct *ComputeTriSrfIsoLines(IPObjectStruct *PObj,
  33.                          int Optimal);
  34.  
  35. /*****************************************************************************
  36. * DESCRIPTION:                                                               M
  37. * Routine to reverse a curve.                             M
  38. *                                                                            *
  39. * PARAMETERS:                                                                M
  40. *   CrvObj:     Curve to reverse its parametrization.                        M
  41. *                                                                            *
  42. * RETURN VALUE:                                                              M
  43. *   IPObjectStruct *:    Reversed curve.                                     M
  44. *                                                                            *
  45. * KEYWORDS:                                                                  M
  46. *   CurveReverse                                                             M
  47. *****************************************************************************/
  48. IPObjectStruct *CurveReverse(IPObjectStruct *CrvObj)
  49. {
  50.      CagdCrvStruct
  51.     *RevCrv = CagdCrvReverse(CrvObj -> U.Crvs);
  52.  
  53.     if (RevCrv == NULL)
  54.     return NULL;
  55.  
  56.     CrvObj = GenCRVObject(RevCrv);
  57.  
  58.     return CrvObj;
  59. }
  60.  
  61. /*****************************************************************************
  62. * DESCRIPTION:                                                               M
  63. * Routine to reverse a surface.                             M
  64. *                                                                            *
  65. * PARAMETERS:                                                                M
  66. *   SrfObj:     Surface to reverse.                                          M
  67. *                                                                            *
  68. * RETURN VALUE:                                                              M
  69. *   IPObjectStruct *:    Reversed surface. The normal of the reversed        M
  70. *                        surface is flipped with respected to the original   M
  71. *                        surface, SrfObj, by 180 degrees.             M
  72. *                                                                            *
  73. * KEYWORDS:                                                                  M
  74. *   SurfaceReverse                                                           M
  75. *****************************************************************************/
  76. IPObjectStruct *SurfaceReverse(IPObjectStruct *SrfObj)
  77. {
  78.     CagdSrfStruct
  79.     *RevSrf = CagdSrfReverse(SrfObj -> U.Srfs);
  80.  
  81.     if (RevSrf == NULL)
  82.     return NULL;
  83.  
  84.     SrfObj = GenSRFObject(RevSrf);
  85.  
  86.     return SrfObj;
  87. }
  88.  
  89. /*****************************************************************************
  90. * DESCRIPTION:                                                               *
  91. * Routine to convert curve(s) to a piecewise linear polyline approximation   *
  92. * and convert its control polygon into polyline as well.             *
  93. *                                                                            *
  94. * PARAMETERS:                                                                *
  95. *   PObj:       Curves to approximate using piecewise linear approximation.  *
  96. *   Optimal:    Do we want an optimal sampling but expensive approach?       *
  97. *                                                                            *
  98. * RETURN VALUE:                                                              *
  99. *   IPObjectStruct *:   A polyline approximation to PObj.                    *
  100. *****************************************************************************/
  101. static IPObjectStruct *ComputeCurveIsoLines(IPObjectStruct *PObj, int Optimal)
  102. {
  103.     int Resolution = GetResolution(FALSE);
  104.     IPObjectStruct *PObjPoly;
  105.     CagdCrvStruct *Crv;
  106.  
  107.     if (!IP_IS_CRV_OBJ(PObj))
  108.     IritFatalError("Curve was expected.");
  109.  
  110.     if (Resolution < MIN_FREE_FORM_RES)
  111.     Resolution = MIN_FREE_FORM_RES;
  112.  
  113.     PObjPoly = GenPOLYObject(NULL);
  114.     PObjPoly -> Attrs = AttrCopyAttributes(PObj -> Attrs);
  115.     IP_SET_POLYLINE_OBJ(PObjPoly);
  116.     for (Crv = PObj -> U.Crvs; Crv != NULL; Crv = Crv -> Pnext) {
  117.     IPPolygonStruct *Poly;
  118.  
  119.     Poly = IritCurve2Polylines(Crv, Resolution,
  120.                    (SymbCrvApproxMethodType) Optimal);
  121.  
  122.     Poly -> Pnext = PObjPoly -> U.Pl;
  123.     PObjPoly -> U.Pl = Poly;
  124.     }
  125.  
  126.     return PObjPoly;
  127. }
  128.  
  129. /*****************************************************************************
  130. * DESCRIPTION:                                                               *
  131. * Routine to convert a surface to a set of piecewise linear polyline         *
  132. * approximation and convert its control mesh into set of polyline as well.   *
  133. *                                                                            *
  134. * PARAMETERS:                                                                *
  135. *   PObj:        Surfaces to apporximate as a mesh of piecewise linear       *
  136. *         isocurves.                                                  *
  137. *   Optimal:     Do we want an optimal sampling but expensive approach?      *
  138. *                                                                            *
  139. * RETURN VALUE:                                                              *
  140. *   IPObjectStruct *:  A polyline object approximating PObj.                 *
  141. *****************************************************************************/
  142. static IPObjectStruct *ComputeSurfaceIsoLines(IPObjectStruct *PObj,
  143.                           int Optimal)
  144. {
  145.     int Resolution = GetResolution(FALSE);
  146.     IPObjectStruct *PObjPolys;
  147.     CagdSrfStruct *Srf;
  148.  
  149.     if (!IP_IS_SRF_OBJ(PObj))
  150.     IritFatalError("Surface was expected.");
  151.  
  152.     if (Resolution < MIN_FREE_FORM_RES)
  153.     Resolution = MIN_FREE_FORM_RES;
  154.  
  155.     PObjPolys = GenPOLYObject(NULL);
  156.     PObjPolys -> Attrs = AttrCopyAttributes(PObj -> Attrs);
  157.     IP_SET_POLYLINE_OBJ(PObjPolys);
  158.     for (Srf = PObj -> U.Srfs; Srf != NULL; Srf = Srf -> Pnext) {
  159.     int NumOfIso[2];
  160.     IPPolygonStruct *Polys, *PolyTmp;
  161.  
  162.     NumOfIso[0] = NumOfIso[1] = -Resolution;
  163.     Polys = IritSurface2Polylines(Srf, NumOfIso, Resolution,
  164.                       (SymbCrvApproxMethodType) Optimal);
  165.  
  166.     for (PolyTmp = Polys;
  167.          PolyTmp -> Pnext != NULL;
  168.          PolyTmp = PolyTmp -> Pnext);
  169.     PolyTmp -> Pnext = PObjPolys -> U.Pl;
  170.     PObjPolys -> U.Pl = Polys;
  171.     }
  172.  
  173.     return PObjPolys;
  174. }
  175.  
  176. /*****************************************************************************
  177. * DESCRIPTION:                                                               *
  178. * Routine to convert a trimmed surface to a set of piecewise linear polyline *
  179. * approximation and convert its control mesh into set of polyline as well.   *
  180. *                                                                            *
  181. * PARAMETERS:                                                                *
  182. *   PObj:        Trimmed surfaces to apporximate as a mesh of piecewise      *
  183. *          linear isocurves.                                          *
  184. *   Optimal:     Do we want an optimal sampling but expensive approach?      *
  185. *                                                                            *
  186. * RETURN VALUE:                                                              *
  187. *   IPObjectStruct *:  A polyline object approximating PObj.                 *
  188. *****************************************************************************/
  189. static IPObjectStruct *ComputeTrimSrfIsoLines(IPObjectStruct *PObj,
  190.                           int Optimal)
  191. {
  192.     int Resolution = GetResolution(FALSE);
  193.     IPObjectStruct *PObjPolys;
  194.     TrimSrfStruct *TrimSrf;
  195.  
  196.     if (!IP_IS_TRIMSRF_OBJ(PObj))
  197.     IritFatalError("Trimmed surface was expected.");
  198.  
  199.     if (Resolution < MIN_FREE_FORM_RES)
  200.     Resolution = MIN_FREE_FORM_RES;
  201.  
  202.     PObjPolys = GenPOLYObject(NULL);
  203.     PObjPolys -> Attrs = AttrCopyAttributes(PObj -> Attrs);
  204.     IP_SET_POLYLINE_OBJ(PObjPolys);
  205.     for (TrimSrf = PObj -> U.TrimSrfs;
  206.      TrimSrf != NULL;
  207.      TrimSrf = TrimSrf -> Pnext) {
  208.     int NumOfIso[2];
  209.     IPPolygonStruct *Polys, *PolyTmp;
  210.  
  211.     NumOfIso[0] = NumOfIso[1] = -Resolution;
  212.     Polys = IritTrimSrf2Polylines(TrimSrf, NumOfIso, Resolution,
  213.                       (SymbCrvApproxMethodType) Optimal,
  214.                       TRUE, TRUE);
  215.  
  216.     for (PolyTmp = Polys;
  217.          PolyTmp -> Pnext != NULL;
  218.          PolyTmp = PolyTmp -> Pnext);
  219.     PolyTmp -> Pnext = PObjPolys -> U.Pl;
  220.     PObjPolys -> U.Pl = Polys;
  221.     }
  222.  
  223.     return PObjPolys;
  224. }
  225.  
  226. /*****************************************************************************
  227. * DESCRIPTION:                                                               *
  228. * Routine to convert a trimmed surface to a set of piecewise linear polyline *
  229. * approximation and convert its control mesh into set of polyline as well.   *
  230. *                                                                            *
  231. * PARAMETERS:                                                                *
  232. *   PObj:        Trimmed surfaces to apporximate as a mesh of piecewise      *
  233. *          linear isocurves.                                          *
  234. *   Optimal:     Do we want an optimal sampling but expensive approach?      *
  235. *                                                                            *
  236. * RETURN VALUE:                                                              *
  237. *   IPObjectStruct *:  A polyline object approximating PObj.                 *
  238. *****************************************************************************/
  239. static IPObjectStruct *ComputeTrivarIsoLines(IPObjectStruct *PObj,
  240.                          int Optimal)
  241. {
  242.     int Resolution = GetResolution(FALSE);
  243.     IPObjectStruct *PObjPolys;
  244.     TrivTVStruct *Trivar;
  245.  
  246.     if (!IP_IS_TRIVAR_OBJ(PObj))
  247.     IritFatalError("Trivariate function was expected.");
  248.  
  249.     if (Resolution < MIN_FREE_FORM_RES)
  250.     Resolution = MIN_FREE_FORM_RES;
  251.  
  252.     PObjPolys = GenPOLYObject(NULL);
  253.     PObjPolys -> Attrs = AttrCopyAttributes(PObj -> Attrs);
  254.     IP_SET_POLYLINE_OBJ(PObjPolys);
  255.     for (Trivar = PObj -> U.Trivars;
  256.      Trivar != NULL;
  257.      Trivar = Trivar -> Pnext) {
  258.     int NumOfIso[3],
  259.         Res = MAX(Resolution / 2, 2);
  260.     IPPolygonStruct *Polys, *PolyTmp;
  261.  
  262.     NumOfIso[0] = NumOfIso[1] = NumOfIso[2] = -Res;
  263.     Polys = IritTrivar2Polylines(Trivar, NumOfIso, Resolution,
  264.                      (SymbCrvApproxMethodType) Optimal);
  265.  
  266.     for (PolyTmp = Polys;
  267.          PolyTmp -> Pnext != NULL;
  268.          PolyTmp = PolyTmp -> Pnext);
  269.     PolyTmp -> Pnext = PObjPolys -> U.Pl;
  270.     PObjPolys -> U.Pl = Polys;
  271.     }
  272.  
  273.     return PObjPolys;
  274. }
  275.  
  276. /*****************************************************************************
  277. * DESCRIPTION:                                                               *
  278. * Routine to convert a triangular surface to a set of piecewise linear         *
  279. * polyline approximation and convert its control mesh into set of polyline   *
  280. * as well.                                     *
  281. *                                                                            *
  282. * PARAMETERS:                                                                *
  283. *   PObj:        Triangular surfaces to apporximate as a mesh of piecewise   *
  284. *         linear isocurves.                                           *
  285. *   Optimal:     Do we want an optimal sampling but expensive approach?      *
  286. *                                                                            *
  287. * RETURN VALUE:                                                              *
  288. *   IPObjectStruct *:  A polyline object approximating PObj.                 *
  289. *****************************************************************************/
  290. static IPObjectStruct *ComputeTriSrfIsoLines(IPObjectStruct *PObj,
  291.                          int Optimal)
  292. {
  293.     int Resolution = GetResolution(FALSE);
  294.     IPObjectStruct *PObjPolys;
  295.     TrngTriangSrfStruct *TriSrf;
  296.  
  297.     if (!IP_IS_TRISRF_OBJ(PObj))
  298.     IritFatalError("Triangular surface was expected.");
  299.  
  300.     if (Resolution < MIN_FREE_FORM_RES)
  301.     Resolution = MIN_FREE_FORM_RES;
  302.  
  303.     PObjPolys = GenPOLYObject(NULL);
  304.     PObjPolys -> Attrs = AttrCopyAttributes(PObj -> Attrs);
  305.     IP_SET_POLYLINE_OBJ(PObjPolys);
  306.     for (TriSrf = PObj -> U.TriSrfs;
  307.      TriSrf != NULL;
  308.      TriSrf = TriSrf -> Pnext) {
  309.     int NumOfIso[3];
  310.     IPPolygonStruct *Polys, *PolyTmp;
  311.  
  312.     NumOfIso[0] = NumOfIso[1] = NumOfIso[2] = -Resolution;
  313.     Polys = IritTriSrf2Polylines(TriSrf, NumOfIso, Resolution, Optimal);
  314.  
  315.     for (PolyTmp = Polys;
  316.          PolyTmp -> Pnext != NULL;
  317.          PolyTmp = PolyTmp -> Pnext);
  318.     PolyTmp -> Pnext = PObjPolys -> U.Pl;
  319.     PObjPolys -> U.Pl = Polys;
  320.     }
  321.  
  322.     return PObjPolys;
  323. }
  324.  
  325. /*****************************************************************************
  326. * DESCRIPTION:                                                               M
  327. * Routine to convert a surface to a set of polygons approximating it.         M
  328. *   Result is saved as an attribute on the surface.                 M
  329. *   If, however, approximation already exists, no computation is performed.  M
  330. *                                                                            *
  331. * PARAMETERS:                                                                M
  332. *   PObj:      Surface to approximate using polygons.                        M
  333. *   Normals:   Compute normals as well, if TRUE.                         M
  334. *                                                                            *
  335. * RETURN VALUE:                                                              M
  336. *   void                                                                     M
  337. *                                                                            *
  338. * KEYWORDS:                                                                  M
  339. *   ComputeSurfacePolygons                                                   M
  340. *****************************************************************************/
  341. void ComputeSurfacePolygons(IPObjectStruct *PObj, int Normals)
  342. {
  343.     int    Resolution = GetResolution(FALSE),
  344.     FourPerFlat = GetFourPerFlat(),
  345.     PolyApproxOpt = GetPolyApproxOptimal(),
  346.     PolyApproxUV = GetPolyApproxUV(),
  347.         BoolUVBooleanState = BoolSetParamSurfaceUVVals(TRUE);
  348.     RealType t,
  349.     RelResolution = AttrGetObjectRealAttrib(PObj, "resolution"),
  350.     Tolerance =  GetPolyApproxTol();
  351.     IPPolygonStruct *Polys;
  352.     IPObjectStruct *PObjPoly;
  353.  
  354.     BoolSetParamSurfaceUVVals(BoolUVBooleanState);/* Restore bool_lib state. */
  355.  
  356.     if (AttrGetObjectObjAttrib(PObj, "_polygons") != NULL)
  357.     return;
  358.  
  359.     if (Resolution < MIN_FREE_FORM_RES)
  360.     Resolution = MIN_FREE_FORM_RES;
  361.     if (RelResolution < IP_ATTR_BAD_REAL)
  362.     Resolution = REAL_TO_INT(Resolution * RelResolution);
  363.  
  364. #ifndef __MSDOS__
  365.     /* Make the resolution more reasonable (very slow on MSDOS). */
  366.     Resolution *= 2;
  367. #endif /* __MSDOS__ */
  368.  
  369.     if (AttrGetObjectStrAttrib(PObj, "twoperflat") != NULL)
  370.     FourPerFlat = FALSE;
  371.     if (AttrGetObjectStrAttrib(PObj, "fourperflat") != NULL)
  372.     FourPerFlat = TRUE;
  373.  
  374.     if ((t = AttrGetObjectRealAttrib(PObj, "u_resolution")) < IP_ATTR_BAD_REAL)
  375.         AttrSetRealAttrib(&PObj -> U.Srfs -> Attr, "u_resolution", t);
  376.     if ((t = AttrGetObjectRealAttrib(PObj, "v_resolution")) < IP_ATTR_BAD_REAL)
  377.         AttrSetRealAttrib(&PObj -> U.Srfs -> Attr, "v_resolution", t);
  378.  
  379.     Polys = IritSurface2Polygons(PObj -> U.Srfs, FourPerFlat,
  380.                  PolyApproxOpt ? Tolerance : Resolution,
  381.                  PolyApproxUV || BoolUVBooleanState,
  382.                  Normals, PolyApproxOpt);
  383.     PObjPoly = GenPolyObject("", Polys, NULL);
  384.     PObjPoly -> Attrs = AttrCopyAttributes(PObj -> Attrs);
  385.     AttrSetObjectObjAttrib(PObj, "_polygons", PObjPoly, FALSE);
  386. }
  387.  
  388. /*****************************************************************************
  389. * DESCRIPTION:                                                               M
  390. * Routine to convert a triangular surface to a set of polygons             M
  391. * approximating it.                                 M
  392. *   Result is saved as an attribute on the surface.                 M
  393. *   If, however, approximation already exists, no computation is performed.  M
  394. *                                                                            *
  395. * PARAMETERS:                                                                M
  396. *   PObj:      Triangular surface to approximate using polygons.             M
  397. *   Normals:   Compute normals as well, if TRUE.                         M
  398. *                                                                            *
  399. * RETURN VALUE:                                                              M
  400. *   void                                                                     M
  401. *                                                                            *
  402. * KEYWORDS:                                                                  M
  403. *   ComputeTriSrfPolygons                                                    M
  404. *****************************************************************************/
  405. void ComputeTriSrfPolygons(IPObjectStruct *PObj, int Normals)
  406. {
  407.     int    Resolution = GetResolution(FALSE),
  408.     PolyApproxOpt = GetPolyApproxOptimal(),
  409.     PolyApproxUV = GetPolyApproxUV(),
  410.         BoolUVBooleanState = BoolSetParamSurfaceUVVals(TRUE);
  411.     RealType
  412.     RelResolution = AttrGetObjectRealAttrib(PObj, "resolution"),
  413.     Tolerance =  GetPolyApproxTol();
  414.     IPPolygonStruct *Polys;
  415.     IPObjectStruct *PObjPoly;
  416.  
  417.     BoolSetParamSurfaceUVVals(BoolUVBooleanState);/* Restore bool_lib state. */
  418.  
  419.     if (AttrGetObjectObjAttrib(PObj, "_polygons") != NULL)
  420.     return;
  421.  
  422.     if (Resolution < MIN_FREE_FORM_RES)
  423.     Resolution = MIN_FREE_FORM_RES;
  424.     if (RelResolution < IP_ATTR_BAD_REAL)
  425.     Resolution = REAL_TO_INT(Resolution * RelResolution);
  426.  
  427. #ifndef __MSDOS__
  428.     /* Make the resolution more reasonable (very slow on MSDOS). */
  429.     Resolution *= 2;
  430. #endif /* __MSDOS__ */
  431.  
  432.     Polys = IritTriSrf2Polygons(PObj -> U.TriSrfs,
  433.                 PolyApproxOpt ? Tolerance : Resolution,
  434.                 PolyApproxUV || BoolUVBooleanState,
  435.                 Normals, PolyApproxOpt);
  436.     PObjPoly = GenPolyObject("", Polys, NULL);
  437.     PObjPoly -> Attrs = AttrCopyAttributes(PObj -> Attrs);
  438.     AttrSetObjectObjAttrib(PObj, "_polygons", PObjPoly, FALSE);
  439. }
  440.  
  441. /*****************************************************************************
  442. * DESCRIPTION:                                                               M
  443. * Routine to convert a trimmed surface to a set of polygons approximating it.M
  444. *   Result is saved as an attribute on the trimmed surface.             M
  445. *   If, however, approximation already exists, no computation is performed.  M
  446. *                                                                            *
  447. * PARAMETERS:                                                                M
  448. *   PObj:      Trimmed surface to approximate using polygons.                M
  449. *   Normals:   Compute normals as well, if TRUE.                         M
  450. *                                                                            *
  451. * RETURN VALUE:                                                              M
  452. *   void                                                                     M
  453. *                                                                            *
  454. * KEYWORDS:                                                                  M
  455. *   ComputeTrimSrfPolygons                                                   M
  456. *****************************************************************************/
  457. void ComputeTrimSrfPolygons(IPObjectStruct *PObj, int Normals)
  458. {
  459.     int    Resolution = GetResolution(FALSE),
  460.     FourPerFlat = GetFourPerFlat(),
  461.     PolyApproxOpt = GetPolyApproxOptimal(),
  462.     PolyApproxUV = GetPolyApproxUV();
  463.     RealType t,
  464.     RelResolution = AttrGetObjectRealAttrib(PObj, "resolution"),
  465.     Tolerance =  GetPolyApproxTol();
  466.     IPPolygonStruct *Polys;
  467.     IPObjectStruct *PObjPoly;
  468.  
  469.     if (AttrGetObjectObjAttrib(PObj, "_polygons") != NULL)
  470.     return;
  471.  
  472.     if (Resolution < MIN_FREE_FORM_RES)
  473.     Resolution = MIN_FREE_FORM_RES;
  474.     if (RelResolution < IP_ATTR_BAD_REAL)
  475.     Resolution = REAL_TO_INT(Resolution * RelResolution);
  476.  
  477. #ifndef __MSDOS__
  478.     /* Make the resolution more reasonable (very slow on MSDOS). */
  479.     Resolution *= 2;
  480. #endif /* __MSDOS__ */
  481.  
  482.     if (AttrGetObjectStrAttrib(PObj, "twoperflat") != NULL)
  483.     FourPerFlat = FALSE;
  484.     if (AttrGetObjectStrAttrib(PObj, "fourperflat") != NULL)
  485.     FourPerFlat = TRUE;
  486.  
  487.     if ((t = AttrGetObjectRealAttrib(PObj, "u_resolution")) < IP_ATTR_BAD_REAL)
  488.         AttrSetRealAttrib(&PObj -> U.TrimSrfs -> Attr, "u_resolution", t);
  489.     if ((t = AttrGetObjectRealAttrib(PObj, "v_resolution")) < IP_ATTR_BAD_REAL)
  490.         AttrSetRealAttrib(&PObj -> U.TrimSrfs -> Attr, "v_resolution", t);
  491.  
  492.     Polys = IritTrimSrf2Polygons(PObj -> U.TrimSrfs, FourPerFlat,
  493.                  PolyApproxOpt ? Tolerance : Resolution,
  494.                  PolyApproxUV, Normals, PolyApproxOpt);
  495.     PObjPoly = GenPolyObject("", Polys, NULL);
  496.     PObjPoly -> Attrs = AttrCopyAttributes(PObj -> Attrs);
  497.     AttrSetObjectObjAttrib(PObj, "_polygons", PObjPoly, FALSE);
  498. }
  499.  
  500. /*****************************************************************************
  501. * DESCRIPTION:                                                               M
  502. * Routine to convert a surface/list of surfaces into set of polygons.         M
  503. *                                                                            *
  504. * PARAMETERS:                                                                M
  505. *   Obj:       A geometry to convert and approximate using polygons.         M
  506. *   RNormals:   Do we want normals as well (at vertices)?                    M
  507. *                                                                            *
  508. * RETURN VALUE:                                                              M
  509. *   IPObjectStruct *:   A polygonal object approximating Obj.                M
  510. *                                                                            *
  511. * KEYWORDS:                                                                  M
  512. *   Geometry2Polygons                                                        M
  513. *****************************************************************************/
  514. IPObjectStruct *Geometry2Polygons(IPObjectStruct *Obj, RealType *RNormals)
  515. {
  516.     IPObjectStruct *PObj;
  517.     int Normals = REAL_PTR_TO_INT(RNormals);
  518.  
  519.     if (IP_IS_SRF_OBJ(Obj) ||
  520.     IP_IS_TRISRF_OBJ(Obj) ||
  521.     IP_IS_TRIMSRF_OBJ(Obj)) {
  522.     if (AttrGetObjectObjAttrib(Obj, "_polygons") != NULL)
  523.         AttrFreeOneAttribute(&Obj -> Attrs, "_polygons");
  524.  
  525.     if (IP_IS_SRF_OBJ(Obj))
  526.         ComputeSurfacePolygons(Obj, Normals);
  527.     else if (IP_IS_TRISRF_OBJ(Obj))
  528.         ComputeTriSrfPolygons(Obj, Normals);
  529.     else if (IP_IS_TRIMSRF_OBJ(Obj))
  530.         ComputeTrimSrfPolygons(Obj, Normals);
  531.  
  532.     PObj = CopyObject(NULL, AttrGetObjectObjAttrib(Obj, "_polygons"),
  533.                                     FALSE);
  534.     AttrSetObjectColor(PObj, GlblPrimColor);   /* Set its default color. */
  535.  
  536.     if (!Normals) {
  537.         IPPolygonStruct *Pl;
  538.  
  539.         for (Pl = PObj -> U.Pl; Pl != NULL; Pl = Pl -> Pnext) {
  540.         IPVertexStruct
  541.             *V = Pl -> PVertex;
  542.  
  543.         do {
  544.             IP_RST_NORMAL_VRTX(V);
  545.  
  546.             V = V -> Pnext;
  547.         }
  548.         while (V != NULL && V != Pl -> PVertex);
  549.         }
  550.     }
  551.  
  552.     return PObj;
  553.     }
  554.     else if (IP_IS_OLST_OBJ(Obj))
  555.     {
  556.     int i = 0;
  557.     IPPolygonStruct *P;
  558.     IPObjectStruct
  559.         *PObjAll = NULL;
  560.  
  561.         while ((PObj = ListObjectGet(Obj, i++)) != NULL) {
  562.         PObj = Geometry2Polygons(PObj, RNormals);
  563.  
  564.         if (PObjAll) {
  565.         if (PObj -> U.Pl) {
  566.             for (P = PObj -> U.Pl;
  567.              P -> Pnext != NULL;
  568.              P = P -> Pnext);
  569.             P -> Pnext = PObjAll -> U.Pl;
  570.             PObjAll -> U.Pl = PObj -> U.Pl;
  571.             PObj -> U.Pl = NULL;
  572.         }
  573.         IPFreeObject(PObj);
  574.         }
  575.         else {
  576.         PObjAll = PObj;
  577.         }
  578.     }
  579.  
  580.     return PObjAll;
  581.     }
  582.     else {
  583.     WndwInputWindowPutStr("Unconvertable to polygons object ignored");
  584.     return NULL;
  585.     }
  586. }
  587.  
  588. /*****************************************************************************
  589. * DESCRIPTION:                                                               M
  590. * Routine to convert a surface/curve/list of these into set of polylines.    M
  591. *                                                                            *
  592. * PARAMETERS:                                                                M
  593. *   Obj:       A geometry to convert and approximate using polygons.         M
  594. *   Optimal:   Do we want an optimal sampling but expensive approach?        M
  595. *                                                                            *
  596. * RETURN VALUE:                                                              M
  597. *   IPObjectStruct *:   A polyline object approximating Obj.                 M
  598. *                                                                            *
  599. * KEYWORDS:                                                                  M
  600. *   Geometry2Polylines                                                       M
  601. *****************************************************************************/
  602. IPObjectStruct *Geometry2Polylines(IPObjectStruct *Obj, RealType *Optimal)
  603. {
  604.     IPObjectStruct *PObj;
  605.     IPPolygonStruct *P;
  606.  
  607.     if (IP_IS_CRV_OBJ(Obj)) {
  608.     return ComputeCurveIsoLines(Obj, REAL_PTR_TO_INT(Optimal));
  609.     }
  610.     else if (IP_IS_SRF_OBJ(Obj)) {
  611.     return ComputeSurfaceIsoLines(Obj, REAL_PTR_TO_INT(Optimal));
  612.     }
  613.     else if (IP_IS_TRIMSRF_OBJ(Obj)) {
  614.     return ComputeTrimSrfIsoLines(Obj, REAL_PTR_TO_INT(Optimal));
  615.     }
  616.     else if (IP_IS_TRIVAR_OBJ(Obj)) {
  617.     return ComputeTrivarIsoLines(Obj, REAL_PTR_TO_INT(Optimal));
  618.     }
  619.     else if (IP_IS_TRISRF_OBJ(Obj)) {
  620.     return ComputeTriSrfIsoLines(Obj, REAL_PTR_TO_INT(Optimal));
  621.     }
  622.     else if (IP_IS_OLST_OBJ(Obj))
  623.     {
  624.     int i = 0;
  625.     IPObjectStruct
  626.         *PObjAll = NULL;
  627.  
  628.         while ((PObj = ListObjectGet(Obj, i++)) != NULL) {
  629.         PObj = Geometry2Polylines(PObj, Optimal);
  630.  
  631.         if (PObjAll) {
  632.         if (PObj -> U.Pl) {
  633.             for (P = PObj -> U.Pl;
  634.              P -> Pnext != NULL;
  635.              P = P -> Pnext);
  636.             P -> Pnext = PObjAll -> U.Pl;
  637.             PObjAll -> U.Pl = PObj -> U.Pl;
  638.             PObj -> U.Pl = NULL;
  639.         }
  640.         IPFreeObject(PObj);
  641.         }
  642.         else {
  643.         PObjAll = PObj;
  644.         }
  645.     }
  646.  
  647.     return PObjAll;
  648.     }
  649.     else {
  650.     return NULL;
  651.     }
  652. }
  653.  
  654. /*****************************************************************************
  655. * DESCRIPTION:                                                               M
  656. * Routine to return extremum value of control mesh/polygon.             M
  657. *                                                                            *
  658. * PARAMETERS:                                                                M
  659. *   Obj:      Object to bound itsextremum possible values.                   M
  660. *   Min:      TRUE for minimum, FALSE for maximum.                           M
  661. *                                                                            *
  662. * RETURN VALUE:                                                              M
  663. *   IPObjectStruct *:   A control points with extremum values. Rational are  M
  664. *                       Correctly porjected back to Euclidean space.         M
  665. *                                                                            *
  666. * KEYWORDS:                                                                  M
  667. *   ExtremumControlPointVals                                                 M
  668. *****************************************************************************/
  669. IPObjectStruct *ExtremumControlPointVals(IPObjectStruct *Obj, CagdRType *Min)
  670. {
  671.     CagdBType
  672.     FindMin = REAL_PTR_TO_INT(Min);
  673.     CagdRType *Extremum,
  674.     **Points = NULL;
  675.     int Len = 0;
  676.     CagdPointType
  677.     PType  = CAGD_PT_E1_TYPE;
  678.  
  679.     if (IP_IS_SRF_OBJ(Obj)) {
  680.     Points = Obj -> U.Srfs -> Points;
  681.     Len = Obj -> U.Srfs -> ULength * Obj -> U.Srfs -> VLength;
  682.     PType = Obj -> U.Srfs -> PType;
  683.     }
  684.     else if (IP_IS_CRV_OBJ(Obj)) {
  685.     Points = Obj -> U.Crvs -> Points;
  686.     Len = Obj -> U.Crvs -> Length;
  687.     PType = Obj -> U.Crvs -> PType;
  688.     }
  689.     else {
  690.     IritNonFatalError("Extremum allowed on curves/surfaces only");
  691.     return NULL;
  692.     }
  693.  
  694.     Extremum = SymbExtremumCntPtVals(Points, Len, FindMin);
  695.  
  696.     return GenCTLPTObject(PType, Extremum, NULL);
  697. }
  698.  
  699. /*****************************************************************************
  700. * DESCRIPTION:                                                               M
  701. * Creates an exact rational quadratic circle parallel to the XY plane.         M
  702. *                                                                            *
  703. * PARAMETERS:                                                                M
  704. *   Position:   Center of circle.                                            M
  705. *   Radius:     Radius of circle.                                            M
  706. *                                                                            *
  707. * RETURN VALUE:                                                              M
  708. *   IPObjectStruct *:   A rational quadratic Bspline curve object          M
  709. *            representing a circle.                     M
  710. *                                                                            *
  711. * KEYWORDS:                                                                  M
  712. *   GenCircleCurveObject                                                     M
  713. *****************************************************************************/
  714. IPObjectStruct *GenCircleCurveObject(VectorType Position, RealType *Radius)
  715. {
  716.     int i;
  717.     CagdPtStruct Pos;
  718.     CagdCrvStruct *CircCrv;
  719.     IPObjectStruct *CrvObj;
  720.  
  721.     for (i = 0; i < 3; i++)
  722.     Pos.Pt[i] = Position[i];
  723.     CircCrv = BspCrvCreateCircle(&Pos, *Radius);
  724.  
  725.     if (CircCrv == NULL)
  726.     return NULL;
  727.  
  728.     CrvObj = GenCRVObject(CircCrv);
  729.  
  730.     return CrvObj;
  731. }
  732.  
  733. /*****************************************************************************
  734. * DESCRIPTION:                                                               M
  735. * Creates an approximated cubic polynomial circle parallel to the XY plane.  M
  736. *                                                                            *
  737. * PARAMETERS:                                                                M
  738. *   Position:   Center of circle.                                            M
  739. *   Radius:     Radius of circle.                                            M
  740. *                                                                            *
  741. * RETURN VALUE:                                                              M
  742. *   IPObjectStruct *:   A cubic polynomial Bspline curve object          M
  743. *            representing a circle.                     M
  744. *                                                                            *
  745. * KEYWORDS:                                                                  M
  746. *   GenPCircleCurveObject                                                    M
  747. *****************************************************************************/
  748. IPObjectStruct *GenPCircleCurveObject(VectorType Position, RealType *Radius)
  749. {
  750.     int i;
  751.     CagdPtStruct Pos;
  752.     CagdCrvStruct *CircCrv;
  753.     IPObjectStruct *CrvObj;
  754.  
  755.     for (i = 0; i < 3; i++)
  756.     Pos.Pt[i] = Position[i];
  757.     CircCrv = BspCrvCreatePCircle(&Pos, *Radius);
  758.  
  759.     if (CircCrv == NULL)
  760.     return NULL;
  761.  
  762.     CrvObj = GenCRVObject(CircCrv);
  763.  
  764.     return CrvObj;
  765. }
  766.  
  767. /*****************************************************************************
  768. * DESCRIPTION:                                                               M
  769. * Creates an arbitrary arc specified by Two end points and Center. Arc must  M
  770. * be less than 180 degree.                             M
  771. *                                                                            *
  772. * PARAMETERS:                                                                M
  773. *   Start:    Location of arc.                                               M
  774. *   Center:   Location of arc.                                               M
  775. *   End:      Location of arc.                                               M
  776. *                                                                            *
  777. * RETURN VALUE:                                                              M
  778. *   IPObjectStruct *:  A curve representing the requested arc.               M
  779. *                                                                            *
  780. * KEYWORDS:                                                                  M
  781. *   GenArcCurveObject                                                        M
  782. *****************************************************************************/
  783. IPObjectStruct *GenArcCurveObject(VectorType Start,
  784.                   VectorType Center,
  785.                   VectorType End)
  786. {
  787.     int i;
  788.     CagdPtStruct StartPt, CenterPt, EndPt;
  789.     CagdCrvStruct *ArcCrv;
  790.     IPObjectStruct *CrvObj;
  791.  
  792.     for (i = 0; i < 3; i++) {
  793.     StartPt.Pt[i] = Start[i];
  794.     CenterPt.Pt[i] = Center[i];
  795.     EndPt.Pt[i] = End[i];
  796.     }
  797.     ArcCrv = BzrCrvCreateArc(&StartPt, &CenterPt, &EndPt);
  798.  
  799.     if (ArcCrv == NULL)
  800.     return NULL;
  801.  
  802.     CrvObj = GenCRVObject(ArcCrv);
  803.  
  804.     return CrvObj;
  805. }
  806.  
  807. /*****************************************************************************
  808. * DESCRIPTION:                                                               M
  809. * Constructs a ruled surface out of the two provided curves.             M
  810. *                                                                            *
  811. * PARAMETERS:                                                                M
  812. *   Obj1, Obj2:  Two polys/curves to rule a surface between.                 M
  813. *                                                                            *
  814. * RETURN VALUE:                                                              M
  815. *   IPObjectStruct *: A ruled surface object.                                M
  816. *                                                                            *
  817. * KEYWORDS:                                                                  M
  818. *   GenRuledSrfObject                                                        M
  819. *****************************************************************************/
  820. IPObjectStruct *GenRuledSrfObject(IPObjectStruct *Obj1, IPObjectStruct *Obj2)
  821. {
  822.     IPObjectStruct
  823.     *SrfObj = NULL;
  824.  
  825.     if (IP_IS_POLY_OBJ(Obj1) && IP_IS_POLY_OBJ(Obj2)) {
  826.     SrfObj = PrimGenRULEDObject(Obj1, Obj2);
  827.     }
  828.     else if (IP_IS_CRV_OBJ(Obj1) && IP_IS_CRV_OBJ(Obj2)) {
  829.     CagdSrfStruct
  830.         *RuledSrf = CagdRuledSrf(Obj1 -> U.Crvs, Obj2 -> U.Crvs, 2, 2);
  831.  
  832.     if (RuledSrf == NULL)
  833.         return NULL;
  834.  
  835.     SrfObj = GenSRFObject(RuledSrf);
  836.     }
  837.     else {
  838.     IritFatalError("RuledSrf: improper input geometry to ruled surface!");
  839.     }
  840.  
  841.     return SrfObj;
  842. }
  843.  
  844. /*****************************************************************************
  845. * DESCRIPTION:                                                               M
  846. * Construct a boolean sum surface out of a single boundary curve.         M
  847. *                                                                            *
  848. * PARAMETERS:                                                                M
  849. *   BndryCrv:  A curve to fill its interior with a surface. Better be close. M
  850. *                                                                            *
  851. * RETURN VALUE:                                                              M
  852. *   IPObjectStruct *: A filling surface object.                              M
  853. *                                                                            *
  854. * KEYWORDS:                                                                  M
  855. *   GenBoolOneSrfObject                                                      M
  856. *****************************************************************************/
  857. IPObjectStruct *GenBoolOneSrfObject(IPObjectStruct *BndryCrv)
  858. {
  859.     IPObjectStruct *SrfObj;
  860.     CagdSrfStruct
  861.     *BoolSumSrf = CagdOneBoolSumSrf(BndryCrv -> U.Crvs);
  862.  
  863.     if (BoolSumSrf == NULL)
  864.     return NULL;
  865.  
  866.     SrfObj = GenSRFObject(BoolSumSrf);
  867.  
  868.     return SrfObj;
  869. }
  870.  
  871. /*****************************************************************************
  872. * DESCRIPTION:                                                               M
  873. * Construct a boolean sum surface out of the four provided curves.         M
  874. *                                                                            *
  875. * PARAMETERS:                                                                M
  876. *   Crv1, Crv2, Crv3, Crv4:  Four curves to construct a Boolean sum between. M
  877. *                                                                            *
  878. * RETURN VALUE:                                                              M
  879. *   IPObjectStruct *:  The Boolean sum surface.                              M
  880. *                                                                            *
  881. * KEYWORDS:                                                                  M
  882. *   GenBoolSumSrfObject                                                      M
  883. *****************************************************************************/
  884. IPObjectStruct *GenBoolSumSrfObject(IPObjectStruct *Crv1,
  885.                     IPObjectStruct *Crv2,
  886.                     IPObjectStruct *Crv3,
  887.                     IPObjectStruct *Crv4)
  888. {
  889.     IPObjectStruct *SrfObj;
  890.     CagdSrfStruct
  891.     *BoolSumSrf = CagdBoolSumSrf(Crv1 -> U.Crvs,
  892.                      Crv2 -> U.Crvs,
  893.                      Crv3 -> U.Crvs,
  894.                      Crv4 -> U.Crvs);
  895.  
  896.     if (BoolSumSrf == NULL)
  897.     return NULL;
  898.  
  899.     SrfObj = GenSRFObject(BoolSumSrf);
  900.  
  901.     return SrfObj;
  902. }
  903.  
  904. /*****************************************************************************
  905. * DESCRIPTION:                                                               M
  906. * Construct a surface out of the provided curve list.                 M
  907. *                                                                            *
  908. * PARAMETERS:                                                                M
  909. *   CrvList:     A list of curves to approximate a surface through.          M
  910. *   OtherOrder:  Other order of surface.                                     M
  911. *                                                                            *
  912. * RETURN VALUE:                                                              M
  913. *   IPObjectStruct *:   A surface approximately traversing through the given M
  914. *                       curves.                                              M
  915. *                                                                            *
  916. * KEYWORDS:                                                                  M
  917. *   GenSrfFromCrvsObject                                                     M
  918. *****************************************************************************/
  919. IPObjectStruct *GenSrfFromCrvsObject(IPObjectStruct *CrvList,
  920.                      RealType *OtherOrder)
  921. {
  922.     int i,
  923.     NumCrvs = 0;
  924.     IPObjectStruct *SrfObj, *CrvObj;
  925.     CagdSrfStruct *Srf;
  926.     CagdCrvStruct *Crv,
  927.     *Crvs = NULL;
  928.  
  929.     if (!IP_IS_OLST_OBJ(CrvList))
  930.     IritFatalError("SURFACE: Not object list object!");
  931.  
  932.     while ((CrvObj = ListObjectGet(CrvList, NumCrvs)) != NULL) {
  933.     if (!IP_IS_CRV_OBJ(CrvObj)) {
  934.         IritNonFatalError("SURFACE: List contains non curve object(s).");
  935.         return NULL;
  936.     }
  937.     if (CrvObj -> U.Crvs -> Pnext != NULL) {
  938.         IritNonFatalError("SURFACE: nested curve lists are disallowed.");
  939.         return NULL;
  940.     }
  941.     NumCrvs++;
  942.     }
  943.  
  944.     /* Chain all curves into a single list and invoke the srf constructor: */
  945.     for (i = 0; i < NumCrvs; i++) {
  946.     CrvObj = ListObjectGet(CrvList, i);
  947.     Crv = CagdCrvCopy(CrvObj -> U.Crvs);
  948.     LIST_PUSH(Crv, Crvs);
  949.     }
  950.  
  951.     Crvs = CagdListReverse(Crvs);
  952.     Srf = CagdSrfFromCrvs(Crvs, REAL_PTR_TO_INT(OtherOrder));
  953.     CagdCrvFreeList(Crvs);
  954.  
  955.     if (Srf == NULL)
  956.     return NULL;
  957.  
  958.     SrfObj = GenSRFObject(Srf);
  959.  
  960.     return SrfObj;
  961. }
  962.  
  963. /*****************************************************************************
  964. * DESCRIPTION:                                                               M
  965. * Constructs a Sweep surface out of the CrossSection curve, Axis curve and   M
  966. * optional Scaling curve and Scaler which scales the CrossSection.         M
  967. *                                                                            *
  968. * PARAMETERS:                                                                M
  969. *   CrossSection:  Cross section of sweep.                                   M
  970. *   Axis:          Axis curve of sweep.                                      M
  971. *   Frame:         Orientation specification. Either an orientation curve    M
  972. *           Or a vector specification.                     M
  973. *                                                                            *
  974. * RETURN VALUE:                                                              M
  975. *   IPObjectStruct *:  A sweep surface.                                      M
  976. *                                                                            *
  977. * KEYWORDS:                                                                  M
  978. *   GenSweepSrfObject                                                        M
  979. *****************************************************************************/
  980. IPObjectStruct *GenSweepSrfObject(IPObjectStruct *CrossSection,
  981.                   IPObjectStruct *Axis,
  982.                   IPObjectStruct *Frame)
  983. {
  984.     IPObjectStruct *SrfObj;
  985.     int FrameIsCrv = IP_IS_CRV_OBJ(Frame),
  986.     HasFrame = FrameIsCrv || IP_IS_VEC_OBJ(Frame);
  987.     CagdSrfStruct *SweepSrf;
  988.  
  989.     SweepSrf = CagdSweepSrf(CrossSection -> U.Crvs, Axis -> U.Crvs, NULL, 1.0,
  990.                 HasFrame ? (FrameIsCrv
  991.                             ? (VoidPtr) Frame -> U.Crvs
  992.                             : (VoidPtr) Frame -> U.Vec)
  993.                      : NULL,
  994.                 FrameIsCrv);
  995.  
  996.     if (SweepSrf == NULL)
  997.     return NULL;
  998.  
  999.     SrfObj = GenSRFObject(SweepSrf);
  1000.  
  1001.     return SrfObj;
  1002. }
  1003.  
  1004. /*****************************************************************************
  1005. * DESCRIPTION:                                                               M
  1006. * Constructs a Sweep surface out of the CrossSection curve, Axis curve and   M
  1007. * optional Scaling curve and Scaler which scales the CrossSection.         M
  1008. *                                                                            *
  1009. * PARAMETERS:                                                                M
  1010. *   CrossSection:  Cross section of sweep.                                   M
  1011. *   Axis:          Axis curve of sweep.                                      M
  1012. *   Scale:         Either a numeric constant scale or a scaling scalar curve.M
  1013. *   Frame:         Orientation specification. Either an orientation curve    M
  1014. *           Or a vector specification.                     M
  1015. *   RRefine:       Refinement control.                                     M
  1016. *                                                                            *
  1017. * RETURN VALUE:                                                              M
  1018. *   IPObjectStruct *:  A sweep surface.                                      M
  1019. *                                                                            *
  1020. * KEYWORDS:                                                                  M
  1021. *   GenSweepScaleSrfObject                                                   M
  1022. *****************************************************************************/
  1023. IPObjectStruct *GenSweepScaleSrfObject(IPObjectStruct *CrossSection,
  1024.                        IPObjectStruct *Axis,
  1025.                        IPObjectStruct *Scale,
  1026.                        IPObjectStruct *Frame,
  1027.                        RealType *RRefine)
  1028. {
  1029.     IPObjectStruct *SrfObj;
  1030.     int FrameIsCrv = IP_IS_CRV_OBJ(Frame),
  1031.     HasFrame = FrameIsCrv || IP_IS_VEC_OBJ(Frame),
  1032.     Refine = REAL_PTR_TO_INT(RRefine);
  1033.     CagdCrvStruct
  1034.     *AxisCrv = Axis -> U.Crvs;
  1035.     CagdSrfStruct *SweepSrf;
  1036.  
  1037.     if (IP_IS_CRV_OBJ(Scale)) {
  1038.     CagdCrvStruct
  1039.         *TCrv = CagdSweepAxisRefine(AxisCrv, Scale -> U.Crvs, Refine);
  1040.  
  1041.     AxisCrv = TCrv;
  1042.     }
  1043.  
  1044.     SweepSrf = CagdSweepSrf(CrossSection -> U.Crvs, AxisCrv,
  1045.                 IP_IS_CRV_OBJ(Scale) ? Scale -> U.Crvs : NULL,
  1046.                 IP_IS_NUM_OBJ(Scale) ? Scale -> U.R : 1.0,
  1047.                 HasFrame ? (FrameIsCrv
  1048.                             ? (VoidPtr) Frame -> U.Crvs
  1049.                             : (VoidPtr) Frame -> U.Vec)
  1050.                      : NULL,
  1051.                 FrameIsCrv);
  1052.  
  1053.     if (AxisCrv != Axis -> U.Crvs)
  1054.     CagdCrvFree(AxisCrv);
  1055.  
  1056.     if (SweepSrf == NULL)
  1057.     return NULL;
  1058.  
  1059.     SrfObj = GenSRFObject(SweepSrf);
  1060.  
  1061.     return SrfObj;
  1062. }
  1063.  
  1064. /*****************************************************************************
  1065. * DESCRIPTION:                                                               M
  1066. * Computes an approximation to the offset of a (planar) curve or a surface.  M
  1067. *                                                                            *
  1068. * PARAMETERS:                                                                M
  1069. *   Obj:        Curve to approximate its offset by Offset amount.            M
  1070. *   Offset:     Amount of offset.                                            M
  1071. *   Tolerance:  Accuracy of offset.                                          M
  1072. *   BezInterp:  Do we want Bezier interpolation or approximation?            M
  1073. *                                                                            *
  1074. * RETURN VALUE:                                                              M
  1075. *   IPObjectStruct *:    An offset approximating to Obj.                     M
  1076. *                                                                            *
  1077. * KEYWORDS:                                                                  M
  1078. *   GenOffsetObject                                                          M
  1079. *****************************************************************************/
  1080. IPObjectStruct *GenOffsetObject(IPObjectStruct *Obj,
  1081.                 RealType *Offset,
  1082.                 RealType *Tolerance,
  1083.                 RealType *BezInterp)
  1084. {
  1085.     if (IP_IS_POLY_OBJ(Obj)) {
  1086.     IPPolygonStruct
  1087.         *Pl = GMPolyOffset(Obj -> U.Pl, IP_IS_POLYGON_OBJ(Obj),
  1088.                    *Offset, NULL);
  1089.     IPObjectStruct 
  1090.         *PlObj = GenPOLYObject(Pl);
  1091.  
  1092.     if (IP_IS_POLYGON_OBJ(Obj))
  1093.         IP_SET_POLYGON_OBJ(PlObj);
  1094.     else
  1095.         IP_SET_POLYLINE_OBJ(PlObj);
  1096.  
  1097.     return PlObj;
  1098.     }
  1099.     else if (IP_IS_SRF_OBJ(Obj)) {
  1100.         IPObjectStruct *SrfObj;
  1101.         CagdSrfStruct
  1102.         *OffsetSrf = SymbSrfSubdivOffset(Obj -> U.Srfs, *Offset,
  1103.                          *Tolerance);
  1104.  
  1105.         if (OffsetSrf == NULL)
  1106.         return NULL;
  1107.  
  1108.         SrfObj = GenSRFObject(OffsetSrf);
  1109.  
  1110.         return SrfObj;
  1111.     }
  1112.     else if (IP_IS_TRIMSRF_OBJ(Obj)) {
  1113.         IPObjectStruct *TSrfObj;
  1114.         CagdSrfStruct
  1115.         *OffsetSrf = SymbSrfSubdivOffset(Obj -> U.TrimSrfs -> Srf,
  1116.                          *Offset, *Tolerance);
  1117.  
  1118.         if (OffsetSrf == NULL)
  1119.         return NULL;
  1120.  
  1121.         TSrfObj = GenTRIMSRFObject(TrimSrfNew(OffsetSrf,
  1122.                  TrimCrvCopyList(Obj -> U.TrimSrfs -> TrimCrvList),
  1123.                           TRUE));
  1124.  
  1125.         return TSrfObj;
  1126.     }
  1127.     else if (IP_IS_CRV_OBJ(Obj)) {
  1128.         IPObjectStruct *CrvObj;
  1129.         CagdCrvStruct
  1130.         *OffsetCrv = SymbCrvSubdivOffset(Obj -> U.Crvs, *Offset,
  1131.                          *Tolerance,
  1132.                          REAL_PTR_TO_INT(BezInterp));
  1133.  
  1134.         if (OffsetCrv == NULL)
  1135.         return NULL;
  1136.  
  1137.         CrvObj = GenCRVObject(OffsetCrv);
  1138.  
  1139.         return CrvObj;
  1140.     }
  1141.     else {
  1142.     IritNonFatalError("Offset allowed on polys/curves/surfaces only");
  1143.     return NULL;
  1144.     }
  1145. }
  1146.  
  1147. /*****************************************************************************
  1148. * DESCRIPTION:                                                               M
  1149. * Computes an approximation to the offset of a (planar) curve or a surface.  M
  1150. *   This offset is computed and approximated to with a given tolerance       M
  1151. * Epsilon that is related to the square of the distance between the original M
  1152. * curve and its offset approximation.                         M
  1153. *   If Trim then regions in the curve with curvature that is larger than     M
  1154. * offset distance required will be trimmed out.                     M
  1155. *                                                                            *
  1156. * PARAMETERS:                                                                M
  1157. *   Obj:        Curve to approximate its offset by Offset amount.            M
  1158. *   Offset:     Amount of offset.                                            M
  1159. *   Epsilon:    Accuracy of offset.                                          M
  1160. *   Trim:       Should we deal with and trim self intersecting loops?        M
  1161. *   BezInterp:  Do we want Bezier interpolation or approximation?            M
  1162. *                                                                            *
  1163. * RETURN VALUE:                                                              M
  1164. *   IPObjectStruct *:    An offset approximating to Obj.                     M
  1165. *                                                                            *
  1166. * KEYWORDS:                                                                  M
  1167. *   GenAOffsetObject                                                         M
  1168. *****************************************************************************/
  1169. IPObjectStruct *GenAOffsetObject(IPObjectStruct *Obj,
  1170.                  RealType *Offset,
  1171.                  RealType *Epsilon,
  1172.                  RealType *Trim,
  1173.                  RealType *BezInterp)
  1174. {
  1175.     if (IP_IS_SRF_OBJ(Obj)) {
  1176.     IritNonFatalError("Adaptive offset is not supported for surfaces");
  1177.     return NULL;
  1178.     }
  1179.     else if (IP_IS_CRV_OBJ(Obj)) {
  1180.         IPObjectStruct *CrvObj;
  1181.         CagdCrvStruct
  1182.         *OffsetCrv = APX_EQ(*Trim, 0.0) ?
  1183.             SymbCrvAdapOffset(Obj -> U.Crvs, *Offset, *Epsilon,
  1184.                   NULL, REAL_PTR_TO_INT(BezInterp)) :
  1185.         SymbCrvAdapOffsetTrim(Obj -> U.Crvs, *Offset,
  1186.                       *Epsilon, NULL,
  1187.                       REAL_PTR_TO_INT(BezInterp));
  1188.  
  1189.         if (OffsetCrv == NULL)
  1190.         return NULL;
  1191.     else
  1192.         CrvObj = GenCRVObject(OffsetCrv);
  1193.  
  1194.         return CrvObj;
  1195.     }
  1196.     else {
  1197.     IritNonFatalError("Offset allowed on curves/surfaces only");
  1198.     return NULL;
  1199.     }
  1200. }
  1201.  
  1202. /*****************************************************************************
  1203. * DESCRIPTION:                                                               M
  1204. * Computes an approximation to the offset of a (planar) curve or a surface.  M
  1205. *   This offset is computed and approximated using a least sqaure fit.         M
  1206. *                                                                            *
  1207. * PARAMETERS:                                                                M
  1208. *   Obj:          Curve to approximate its offset by Offset amount.          M
  1209. *   Offset:       Amount of offset.                                          M
  1210. *   NumOfSamples: To sample the offset curve.                                M
  1211. *   NumOfDOF:     Number of control points in resulting approximation.       M
  1212. *   Order:        Of resulting approximation.                                M
  1213. *                                                                            *
  1214. * RETURN VALUE:                                                              M
  1215. *   IPObjectStruct *:    An offset approximating to Obj.                     M
  1216. *                                                                            *
  1217. * KEYWORDS:                                                                  M
  1218. *   GenLeastSqrOffsetObject                                                  M
  1219. *****************************************************************************/
  1220. IPObjectStruct *GenLeastSqrOffsetObject(IPObjectStruct *Obj,
  1221.                     RealType *Offset,
  1222.                     RealType *NumOfSamples,
  1223.                     RealType *NumOfDOF,
  1224.                     RealType *Order)
  1225. {
  1226.     CagdRType Tolerance;
  1227.  
  1228.     if (IP_IS_CRV_OBJ(Obj)) {
  1229.         CagdCrvStruct
  1230.         *OffsetCrv = SymbCrvLeastSquarOffset(Obj -> U.Crvs,
  1231.                          *Offset,
  1232.                          REAL_PTR_TO_INT(NumOfSamples),
  1233.                          REAL_PTR_TO_INT(NumOfDOF),
  1234.                          REAL_PTR_TO_INT(Order),
  1235.                          &Tolerance);
  1236.  
  1237.         if (OffsetCrv == NULL)
  1238.         return NULL;
  1239.     else
  1240.         return GenCRVObject(OffsetCrv);
  1241.     }
  1242.     else {
  1243.     IritNonFatalError("LOffset allowed on curves only");
  1244.     return NULL;
  1245.     }
  1246. }
  1247.  
  1248. /*****************************************************************************
  1249. * DESCRIPTION:                                                               M
  1250. * Computes an approximation to the offset of a (planar) curve or a surface.  M
  1251. *   This offset is computed and approximated using a tangent field matcing.  M
  1252. *                                                                            *
  1253. * PARAMETERS:                                                                M
  1254. *   Obj:          Curve to approximate its offset by Offset amount.          M
  1255. *   Offset:       Amount of offset.                                          M
  1256. *   Tolerance:    Accuracy of offset, measured in offset direction (normal   M
  1257. *          of curve) angular error, in radians.                       M
  1258. *                                                                            *
  1259. * RETURN VALUE:                                                              M
  1260. *   IPObjectStruct *:    An offset approximating to Obj.                     M
  1261. *                                                                            *
  1262. * KEYWORDS:                                                                  M
  1263. *   GenMatchingOffsetObject                                                  M
  1264. *****************************************************************************/
  1265. IPObjectStruct *GenMatchingOffsetObject(IPObjectStruct *Obj,
  1266.                     RealType *Offset,
  1267.                     RealType *Tolerance)
  1268. {
  1269.     if (IP_IS_CRV_OBJ(Obj)) {
  1270.         CagdCrvStruct
  1271.         *OffsetCrv = SymbCrvMatchingOffset(Obj -> U.Crvs,
  1272.                            *Offset,
  1273.                            *Tolerance);
  1274.  
  1275.         if (OffsetCrv == NULL)
  1276.         return NULL;
  1277.     else
  1278.         return GenCRVObject(OffsetCrv);
  1279.     }
  1280.     else {
  1281.     IritNonFatalError("MOffset allowed on curves only");
  1282.     return NULL;
  1283.     }
  1284. }
  1285.  
  1286. /*****************************************************************************
  1287. * DESCRIPTION:                                                               M
  1288. * Affine reparametrization, effectively changing the domain of the curve.    M
  1289. *                                                                            *
  1290. * PARAMETERS:                                                                M
  1291. *   Obj:         A curve to change its parametric domain.                    M
  1292. *   TMin, TMax:  New domain for Obj.                         M
  1293. *                                                                            *
  1294. * RETURN VALUE:                                                              M
  1295. *   IPObjectStruct *:  A curve identical to Obj but with parametric domain   M
  1296. *                      from TMin to TMax.                                    M
  1297. *                                                                            *
  1298. * KEYWORDS:                                                                  M
  1299. *   CrvReparametrization                                                     M
  1300. *****************************************************************************/
  1301. IPObjectStruct *CrvReparametrization(IPObjectStruct *Obj,
  1302.                      RealType *TMin,
  1303.                      RealType *TMax)
  1304. {
  1305.     IPObjectStruct *CrvObj;
  1306.     CagdCrvStruct
  1307.     *Crv = CAGD_IS_BEZIER_CRV(Obj -> U.Crvs) ?
  1308.               CnvrtBezier2BsplineCrv(Obj -> U.Crvs) :
  1309.               CagdCrvCopy(Obj -> U.Crvs);
  1310.     int Len = CAGD_CRV_PT_LST_LEN(Crv) + Crv -> Order;
  1311.     CagdRType MinDomain, MaxDomain,
  1312.     *KV = Crv -> KnotVector;
  1313.  
  1314.     CagdCrvDomain(Crv, &MinDomain, &MaxDomain);
  1315.  
  1316.     /* Translate to 0.0, scale, and translate to new location. */
  1317.     BspKnotAffineTrans(KV, Len, -MinDomain, 1.0);
  1318.     BspKnotScale(KV, Len, (*TMax - *TMin) / (MaxDomain - MinDomain));
  1319.     BspKnotAffineTrans(KV, Len, *TMin, 1.0);
  1320.     
  1321.     CrvObj = GenCRVObject(Crv);
  1322.  
  1323.     return CrvObj;
  1324. }
  1325.  
  1326. /*****************************************************************************
  1327. * DESCRIPTION:                                                               M
  1328. * Affine reparametrization, effectively changing the domain of the surface.  M
  1329. *                                                                            *
  1330. * PARAMETERS:                                                                M
  1331. *   Obj:         A surface to change its parametric domain.                  M
  1332. *   RDir:        Direction of reparametrization. Either U or V.             M
  1333. *   TMin, TMax:  New domain for Obj.                         M
  1334. *                                                                            *
  1335. * RETURN VALUE:                                                              M
  1336. *   IPObjectStruct *:  A surface identical to Obj but with parametric        M
  1337. *                      domain from TMin to TMax in direction RDir.           M
  1338. *                                                                            *
  1339. * KEYWORDS:                                                                  M
  1340. *   SrfReparametrization                                                     M
  1341. *****************************************************************************/
  1342. IPObjectStruct *SrfReparametrization(IPObjectStruct *Obj,
  1343.                      RealType *RDir,
  1344.                      RealType *TMin,
  1345.                      RealType *TMax)
  1346. {
  1347.     IPObjectStruct *SrfObj;
  1348.     CagdSrfDirType
  1349.     Dir = (CagdSrfDirType) REAL_PTR_TO_INT(RDir);
  1350.     CagdSrfStruct
  1351.     *Srf = CAGD_IS_BEZIER_SRF(Obj -> U.Srfs) ?
  1352.               CnvrtBezier2BsplineSrf(Obj -> U.Srfs) :
  1353.               CagdSrfCopy(Obj -> U.Srfs);
  1354.     int Len = Dir == CAGD_CONST_U_DIR
  1355.                 ? CAGD_SRF_UPT_LST_LEN(Srf) + Srf -> UOrder
  1356.                 : CAGD_SRF_VPT_LST_LEN(Srf) + Srf -> VOrder;
  1357.     CagdRType MinDomain, MaxDomain,
  1358.           MinUDomain, MaxUDomain, MinVDomain, MaxVDomain,
  1359.         *KV = Dir == CAGD_CONST_U_DIR ? Srf -> UKnotVector : Srf -> VKnotVector;
  1360.  
  1361.     CagdSrfDomain(Srf, &MinUDomain, &MaxUDomain, &MinVDomain, &MaxVDomain);
  1362.     if (Dir == CAGD_CONST_U_DIR) {
  1363.         MinDomain = MinUDomain;
  1364.     MaxDomain = MaxUDomain;
  1365.     }
  1366.     else {
  1367.         MinDomain = MinVDomain;
  1368.     MaxDomain = MaxVDomain;
  1369.     }
  1370.  
  1371.     /* Translate to 0.0, scale, and translate to new location. */
  1372.     BspKnotAffineTrans(KV, Len, -MinDomain, 1.0);
  1373.     BspKnotScale(KV, Len, (*TMax - *TMin) / (MaxDomain - MinDomain));
  1374.     BspKnotAffineTrans(KV, Len, *TMin, 1.0);
  1375.  
  1376.     SrfObj = GenSRFObject(Srf);
  1377.  
  1378.     return SrfObj;
  1379. }
  1380.  
  1381. /*****************************************************************************
  1382. * DESCRIPTION:                                                               M
  1383. * Affine reparametrization, effectively changing the domain of the trivar.   M
  1384. *                                                                            *
  1385. * PARAMETERS:                                                                M
  1386. *   Obj:         A trivariate to change its parametric domain.               M
  1387. *   RDir:        Direction of reparametrization. Either U, V or W.         M
  1388. *   TMin, TMax:  New domain for Obj.                         M
  1389. *                                                                            *
  1390. * RETURN VALUE:                                                              M
  1391. *   IPObjectStruct *:  A trivar identical to Obj but with parametric        M
  1392. *                      domain from TMin to TMax in direction RDir.           M
  1393. *                                                                            *
  1394. * KEYWORDS:                                                                  M
  1395. *   TrivReparametrization                                                    M
  1396. *****************************************************************************/
  1397. IPObjectStruct *TrivReparametrization(IPObjectStruct *Obj,
  1398.                       RealType *RDir,
  1399.                       RealType *TMin,
  1400.                       RealType *TMax)
  1401. {
  1402.     IPObjectStruct *TVObj;
  1403.     TrivTVDirType
  1404.     Dir = (TrivTVDirType) REAL_PTR_TO_INT(RDir);
  1405.     TrivTVStruct
  1406.     *TV = TRIV_IS_BEZIER_TV(Obj -> U.Trivars) ?
  1407.               TrivCnvrtBezier2BsplineTV(Obj -> U.Trivars) :
  1408.               TrivTVCopy(Obj -> U.Trivars);
  1409.     int Len;
  1410.     CagdRType *KV, MinDomain, MaxDomain, MinUDomain, MaxUDomain,
  1411.     MinVDomain, MaxVDomain, MinWDomain, MaxWDomain;
  1412.  
  1413.     TrivTVDomain(TV, &MinUDomain, &MaxUDomain,
  1414.              &MinVDomain, &MaxVDomain,
  1415.              &MinWDomain, &MaxWDomain);
  1416.  
  1417.     switch (Dir) {
  1418.         case TRIV_CONST_U_DIR:
  1419.             Len = TRIV_TV_UPT_LST_LEN(TV) + TV -> UOrder;
  1420.         KV = TV -> UKnotVector;
  1421.         MinDomain = MinUDomain;
  1422.         MaxDomain = MaxUDomain;
  1423.         break;
  1424.         case TRIV_CONST_V_DIR:
  1425.             Len = TRIV_TV_VPT_LST_LEN(TV) + TV -> VOrder;
  1426.         KV = TV -> VKnotVector;
  1427.         MinDomain = MinVDomain;
  1428.         MaxDomain = MaxVDomain;
  1429.         break;
  1430.         case TRIV_CONST_W_DIR:
  1431.             Len = TRIV_TV_WPT_LST_LEN(TV) + TV -> WOrder;
  1432.         KV = TV -> WKnotVector;
  1433.         MinDomain = MinWDomain;
  1434.         MaxDomain = MaxWDomain;
  1435.         break;
  1436.     default:
  1437.         IritNonFatalError("TREPARAM: Wrong parametric direction.");
  1438.         return NULL;
  1439.     }
  1440.  
  1441.     /* Translate to 0.0, scale, and translate to new location. */
  1442.     BspKnotAffineTrans(KV, Len, -MinDomain, 1.0);
  1443.     BspKnotScale(KV, Len, (*TMax - *TMin) / (MaxDomain - MinDomain));
  1444.     BspKnotAffineTrans(KV, Len, *TMin, 1.0);
  1445.  
  1446.     TVObj = GenTRIVARObject(TV);
  1447.  
  1448.     return TVObj;
  1449. }
  1450.  
  1451. /*****************************************************************************
  1452. * DESCRIPTION:                                                               M
  1453. * Computes curvature properties of the given curve.                 M
  1454. *                                                                            *
  1455. * PARAMETERS:                                                                M
  1456. *   PObj:      Curve to evaluate its curvature properties.                   M
  1457. *   Eps:       Accuracy of computation.                                      M
  1458. *                                                                            *
  1459. * RETURN VALUE:                                                              M
  1460. *   IPObjectStruct *:  Either extremum curvature locations if Eps > 0, or    M
  1461. *                      curvature field square curve if Eps < 0.              M
  1462. *                                                                            *
  1463. * KEYWORDS:                                                                  M
  1464. *   CrvCurvaturePts                                                          M
  1465. *****************************************************************************/
  1466. IPObjectStruct *CrvCurvaturePts(IPObjectStruct *PObj, RealType *Eps)
  1467.     IPObjectStruct *NewPObj;
  1468.  
  1469.     if (CAGD_NUM_OF_PT_COORD(PObj -> U.Crvs -> PType) < 2 ||
  1470.     CAGD_NUM_OF_PT_COORD(PObj -> U.Crvs -> PType) > 3) {
  1471.     IritNonFatalError(
  1472.         "CCRVTR: Only 2 or 3 dimensional curves are supported.");
  1473.     return NULL;
  1474.     }
  1475.  
  1476.     if (*Eps <= 0.0) {
  1477.     CagdRType TMin, TMax;
  1478.     CagdCrvStruct *CrvtrCrv2D,
  1479.         *CrvtrCrv = SymbCrv3DCurvatureSqr(PObj -> U.Crvs);
  1480.  
  1481.     CagdCrvDomain(PObj -> U.Crvs, &TMin, &TMax);
  1482.     CrvtrCrv2D = SymbPrmtSclrCrvTo2D(CrvtrCrv, TMin, TMax);
  1483.     CagdCrvFree(CrvtrCrv);
  1484.  
  1485.     NewPObj = GenCRVObject(CrvtrCrv2D);
  1486.     }
  1487.     else {
  1488.     int i;
  1489.     CagdPtStruct *IPtsTmp,
  1490.         *IPts = SymbCrv2DExtremCrvtrPts(PObj -> U.Crvs, *Eps);
  1491.  
  1492.     NewPObj = IPAllocObject("", IP_OBJ_LIST_OBJ, NULL);
  1493.  
  1494.     for (IPtsTmp = IPts, i = 0;
  1495.          IPtsTmp != NULL;
  1496.          IPtsTmp = IPtsTmp -> Pnext, i++) {
  1497.         ListObjectInsert(NewPObj, i, GenNUMValObject(IPtsTmp -> Pt[0]));
  1498.     }
  1499.  
  1500.     CagdPtFreeList(IPts);
  1501.  
  1502.     ListObjectInsert(NewPObj, i, NULL);
  1503.     }
  1504.  
  1505.     return NewPObj;
  1506. }
  1507.  
  1508. /*****************************************************************************
  1509. * DESCRIPTION:                                                               M
  1510. * Computes curvature properties of the given surface.                 M
  1511. *                                                                            *
  1512. * PARAMETERS:                                                                M
  1513. *   PObj:     Surface to compute curvature properties for.                   M
  1514. *   RPtType:  Point type of output.                                          M
  1515. *   RDir:     Either curvature in U or V or total upper bound.               M
  1516. *                                                                            *
  1517. * RETURN VALUE:                                                              M
  1518. *   IPObjectStruct *:   A curvature bound field for surface PObj.            M
  1519. *                                                                            *
  1520. * KEYWORDS:                                                                  M
  1521. *   SrfCurvatureBounds                                                       M
  1522. *****************************************************************************/
  1523. IPObjectStruct *SrfCurvatureBounds(IPObjectStruct *PObj,
  1524.                    RealType *RPtType,
  1525.                    RealType *RDir)
  1526.     IPObjectStruct *NewPObj;
  1527.     CagdSrfStruct *TSrf, *CrvtrSrfBound;
  1528.     CagdPointType
  1529.     PtType = (CagdPointType) REAL_PTR_TO_INT(RPtType);
  1530.     CagdSrfDirType
  1531.     Dir = (CagdSrfDirType)  REAL_PTR_TO_INT(RDir);
  1532.  
  1533.     if (CAGD_NUM_OF_PT_COORD(PObj -> U.Srfs -> PType) < 2 ||
  1534.     CAGD_NUM_OF_PT_COORD(PObj -> U.Srfs -> PType) > 3) {
  1535.     IritNonFatalError(
  1536.         "SCRVTR: Only 2 or 3 dimensional curves are supported.");
  1537.     return NULL;
  1538.     }
  1539.  
  1540.     switch (Dir) {
  1541.     case CAGD_CONST_U_DIR:
  1542.     case CAGD_CONST_V_DIR:
  1543.         CrvtrSrfBound = SymbSrfIsoDirNormalCurvatureBound(PObj -> U.Srfs,
  1544.                                     Dir);
  1545.         break;
  1546.     default:
  1547.         CrvtrSrfBound = SymbSrfCurvatureUpperBound(PObj -> U.Srfs);
  1548.         break;
  1549.     }
  1550.  
  1551.     switch (PtType) {
  1552.     case CAGD_PT_P1_TYPE:
  1553.         break;
  1554.     case CAGD_PT_E1_TYPE:
  1555.     case CAGD_PT_E3_TYPE:
  1556.     case CAGD_PT_P3_TYPE:
  1557.         TSrf = CagdCoerceSrfTo(CrvtrSrfBound, PtType);
  1558.         CagdSrfFree(CrvtrSrfBound);
  1559.         CrvtrSrfBound = TSrf;
  1560.         break;
  1561.     default:
  1562.         CagdSrfFree(CrvtrSrfBound);
  1563.         IritNonFatalError("SCRVTR: Wrong point type coercion.");
  1564.         return NULL;
  1565.     }
  1566.  
  1567.     NewPObj = GenSRFObject(CrvtrSrfBound);
  1568.  
  1569.     return NewPObj;
  1570. }
  1571.  
  1572. /*****************************************************************************
  1573. * DESCRIPTION:                                                               M
  1574. * Computes the Gauss curvature surface of the given surface.             M
  1575. *                                                                            *
  1576. * PARAMETERS:                                                                M
  1577. *   PObj:     Surface to compute its gauss curvature surface for.            M
  1578. *                                                                            *
  1579. * RETURN VALUE:                                                              M
  1580. *   IPObjectStruct *:   A Gauss curvature surface of PObj.                   M
  1581. *                                                                            *
  1582. * KEYWORDS:                                                                  M
  1583. *   SrfGaussCurvature                                                        M
  1584. *****************************************************************************/
  1585. IPObjectStruct *SrfGaussCurvature(IPObjectStruct *PObj)
  1586.     IPObjectStruct *NewPObj;
  1587.     CagdSrfStruct *GaussSrf;
  1588.  
  1589.     if (CAGD_NUM_OF_PT_COORD(PObj -> U.Srfs -> PType) < 2 ||
  1590.     CAGD_NUM_OF_PT_COORD(PObj -> U.Srfs -> PType) > 3) {
  1591.     IritNonFatalError(
  1592.         "SGauss: Only 2 or 3 dimensional surfaces are supported.");
  1593.     return NULL;
  1594.     }
  1595.  
  1596.     GaussSrf = SymbSrfGaussCurvature(PObj -> U.Srfs);
  1597.  
  1598.     NewPObj = GenSRFObject(GaussSrf);
  1599.  
  1600.     return NewPObj;
  1601. }
  1602.  
  1603. /*****************************************************************************
  1604. * DESCRIPTION:                                                               M
  1605. * Computes the Mean curvature square surface of the given surface.         M
  1606. *                                                                            *
  1607. * PARAMETERS:                                                                M
  1608. *   PObj:     Surface to compute its mean curvature square surface for.      M
  1609. *                                                                            *
  1610. * RETURN VALUE:                                                              M
  1611. *   IPObjectStruct *:   A Mean curvature square surface of PObj.             M
  1612. *                                                                            *
  1613. * KEYWORDS:                                                                  M
  1614. *   SrfMeanSqrCurvature                                                      M
  1615. *****************************************************************************/
  1616. IPObjectStruct *SrfMeanSqrCurvature(IPObjectStruct *PObj)
  1617.     IPObjectStruct *NewPObj;
  1618.     CagdSrfStruct *MeanSrf;
  1619.  
  1620.     if (CAGD_NUM_OF_PT_COORD(PObj -> U.Srfs -> PType) < 2 ||
  1621.     CAGD_NUM_OF_PT_COORD(PObj -> U.Srfs -> PType) > 3) {
  1622.     IritNonFatalError(
  1623.         "SMeanSqr: Only 2 or 3 dimensional surfaces are supported.");
  1624.     return NULL;
  1625.     }
  1626.  
  1627.     MeanSrf = SymbSrfMeanCurvatureSqr(PObj -> U.Srfs);
  1628.  
  1629.     NewPObj = GenSRFObject(MeanSrf);
  1630.  
  1631.     return NewPObj;
  1632. }
  1633.  
  1634. /*****************************************************************************
  1635. * DESCRIPTION:                                                               M
  1636. * Computes the isoparametric focal surface of the given surface.         M
  1637. *                                                                            *
  1638. * PARAMETERS:                                                                M
  1639. *   PObj:     Surface to compute its focal surface using isoparametric         M
  1640. *          normal curvature direction.                     M
  1641. *   RDir:     Either iso focal surface in U or V.                     M
  1642. *                                                                            *
  1643. * RETURN VALUE:                                                              M
  1644. *   IPObjectStruct *:   An iso focal surface of surface PObj.                M
  1645. *                                                                            *
  1646. * KEYWORDS:                                                                  M
  1647. *   SrfIsoFocalSrf                                                        M
  1648. *****************************************************************************/
  1649. IPObjectStruct *SrfIsoFocalSrf(IPObjectStruct *PObj, RealType *RDir)
  1650.     IPObjectStruct *NewPObj;
  1651.     CagdSrfStruct *IsoFocalSrf;
  1652.     CagdSrfDirType
  1653.     Dir = (CagdSrfDirType) REAL_PTR_TO_INT(RDir);
  1654.  
  1655.     if (CAGD_NUM_OF_PT_COORD(PObj -> U.Srfs -> PType) < 2 ||
  1656.     CAGD_NUM_OF_PT_COORD(PObj -> U.Srfs -> PType) > 3) {
  1657.     IritNonFatalError(
  1658.         "IsoFocal: Only 2 or 3 dimensional surfaces are supported.");
  1659.     return NULL;
  1660.     }
  1661.  
  1662.     IsoFocalSrf = SymbSrfIsoFocalSrf(PObj -> U.Srfs, Dir);
  1663.  
  1664.     NewPObj = GenSRFObject(IsoFocalSrf);
  1665.  
  1666.     return NewPObj;
  1667. }
  1668.  
  1669. /*****************************************************************************
  1670. * DESCRIPTION:                                                               M
  1671. * Computes the (mean) evolute curve/surface of the given curve/surface.         M
  1672. *                                                                            *
  1673. * PARAMETERS:                                                                M
  1674. *   PObj:     Curve/Surface to compute its (mean) evolute for.               M
  1675. *                                                                            *
  1676. * RETURN VALUE:                                                              M
  1677. *   IPObjectStruct *:   A (mean) evolute curve/surface of PObj.              M
  1678. *                                                                            *
  1679. * KEYWORDS:                                                                  M
  1680. *   FreeformEvolute                                                          M
  1681. *****************************************************************************/
  1682. IPObjectStruct *FreeformEvolute(IPObjectStruct *PObj)
  1683.     IPObjectStruct *NewPObj;
  1684.  
  1685.     if (IP_IS_CRV_OBJ(PObj)) {
  1686.     CagdCrvStruct *EvoluteCrv, *EvoluteCrvAux;
  1687.  
  1688.     if (CAGD_NUM_OF_PT_COORD(PObj -> U.Crvs -> PType) < 2 ||
  1689.         CAGD_NUM_OF_PT_COORD(PObj -> U.Crvs -> PType) > 3) {
  1690.         IritNonFatalError(
  1691.         "EVOLUTE: Only 2 or 3 dimensional curves are supported.");
  1692.         return NULL;
  1693.     }
  1694.  
  1695.     EvoluteCrvAux = SymbCrv3DRadiusNormal(PObj -> U.Crvs);
  1696.     EvoluteCrv = SymbCrvAdd(PObj -> U.Crvs, EvoluteCrvAux);
  1697.     CagdCrvFree(EvoluteCrvAux);
  1698.  
  1699.     NewPObj = GenCRVObject(EvoluteCrv);
  1700.     }
  1701.     else if (IP_IS_SRF_OBJ(PObj)) {
  1702.     CagdSrfStruct *EvoluteSrf, *EvoluteSrfAux;
  1703.  
  1704.     if (CAGD_NUM_OF_PT_COORD(PObj -> U.Srfs -> PType) < 2 ||
  1705.         CAGD_NUM_OF_PT_COORD(PObj -> U.Srfs -> PType) > 3) {
  1706.         IritNonFatalError(
  1707.         "EVOLUTE: Only 2 or 3 dimensional surfaces are supported.");
  1708.         return NULL;
  1709.     }
  1710.  
  1711.     EvoluteSrfAux = SymbSrfMeanEvolute(PObj -> U.Srfs);
  1712.     EvoluteSrf = SymbSrfAdd(PObj -> U.Srfs, EvoluteSrfAux);
  1713.     CagdSrfFree(EvoluteSrfAux);
  1714.  
  1715.     NewPObj = GenSRFObject(EvoluteSrf);
  1716.     }
  1717.  
  1718.     return NewPObj;
  1719. }
  1720.  
  1721. /*****************************************************************************
  1722. * DESCRIPTION:                                                               M
  1723. * Merges two surfaces into one in specified Dir and SameEdge flag.          M
  1724. *                                                                            *
  1725. * PARAMETERS:                                                                M
  1726. *   Srf1, Srf2:  Two surfaces to merge.                                      M
  1727. *   Dir:         Direction of merge. Either U or V.                          M
  1728. *   SameEdge:    Do Srf1 and Srf2 share a common edge?                       M
  1729. *                                                                            *
  1730. * RETURN VALUE:                                                              M
  1731. *   IPObjectStruct *:  A surface result of the merge.                        M
  1732. *                                                                            *
  1733. * KEYWORDS:                                                                  M
  1734. *   MergeSrfSrf                                                              M
  1735. *****************************************************************************/
  1736. IPObjectStruct *MergeSrfSrf(IPObjectStruct *Srf1,
  1737.                 IPObjectStruct *Srf2,
  1738.                 RealType *Dir,
  1739.                 RealType *SameEdge)
  1740. {
  1741.     IPObjectStruct *SrfObj;
  1742.     CagdSrfStruct
  1743.     *Srf = CagdMergeSrfSrf(Srf1 -> U.Srfs, Srf2 -> U.Srfs,
  1744.                    (CagdSrfDirType) REAL_PTR_TO_INT(Dir),
  1745.                    REAL_PTR_TO_INT(SameEdge), TRUE);
  1746.  
  1747.     SrfObj = GenSRFObject(Srf);
  1748.  
  1749.     return SrfObj;
  1750. }
  1751.  
  1752. /*****************************************************************************
  1753. * DESCRIPTION:                                                               M
  1754. * Merge two curves/ctl points into one curve by adding a linear segment      M
  1755. * between the first end point to second start point.                 M
  1756. *                                                                            *
  1757. * PARAMETERS:                                                                M
  1758. *   PObj1, PObj2:  Either curve or a control point to merge.                 M
  1759. *                                                                            *
  1760. * RETURN VALUE:                                                              M
  1761. *   IPObjectStruct *:   Merged curve.                                        M
  1762. *                                                                            *
  1763. * KEYWORDS:                                                                  M
  1764. *   MergeCurvesAndCtlPoints                                                  M
  1765. *****************************************************************************/
  1766. IPObjectStruct *MergeCurvesAndCtlPoints(IPObjectStruct *PObj1,
  1767.                     IPObjectStruct *PObj2)
  1768. {
  1769.     IPObjectStruct *CrvObj;
  1770.     CagdCrvStruct
  1771.     *Crv = NULL;
  1772.     CagdPtStruct Pt1, Pt2;
  1773.  
  1774.     if (IP_IS_CRV_OBJ(PObj1)) {
  1775.     if (IP_IS_CRV_OBJ(PObj2)) {
  1776.         Crv = CagdMergeCrvCrv(PObj1 -> U.Crvs, PObj2 -> U.Crvs, TRUE);
  1777.     }
  1778.     else if (IP_IS_CTLPT_OBJ(PObj2)) {
  1779.         CagdRType
  1780.         *Coords2 = PObj2 -> U.CtlPt.Coords;
  1781.  
  1782.         CagdCoerceToE3(Pt2.Pt, &Coords2, -1, PObj2 -> U.CtlPt.PtType);
  1783.         Crv = CagdMergeCrvPt(PObj1 -> U.Crvs, &Pt2);
  1784.     }
  1785.     else
  1786.         IritFatalError("Curve/CtlPt was expected.");
  1787.     }
  1788.     else if (IP_IS_CTLPT_OBJ(PObj1)) {
  1789.     CagdRType
  1790.         *Coords1 = PObj1 -> U.CtlPt.Coords;
  1791.  
  1792.     CagdCoerceToE3(Pt1.Pt, &Coords1, -1, PObj1 -> U.CtlPt.PtType);
  1793.  
  1794.     if (IP_IS_CRV_OBJ(PObj2)) {
  1795.         Crv = CagdMergePtCrv(&Pt1, PObj2 -> U.Crvs);
  1796.     }
  1797.     else if (IP_IS_CTLPT_OBJ(PObj2)) {
  1798.         CagdRType
  1799.         *Coords2 = PObj2 -> U.CtlPt.Coords;
  1800.  
  1801.         CagdCoerceToE3(Pt2.Pt, &Coords2, -1, PObj2 -> U.CtlPt.PtType);
  1802.         Crv = CagdMergePtPt(&Pt1, &Pt2);
  1803.     }
  1804.     else
  1805.         IritFatalError("Curve/CtlPt was expected.");
  1806.     }
  1807.     else
  1808.     IritFatalError("Curve/CtlPt was expected.");
  1809.  
  1810.     if (Crv == NULL)
  1811.     return NULL;
  1812.  
  1813.     CrvObj = GenCRVObject(Crv);
  1814.  
  1815.     return CrvObj;
  1816. }
  1817.